/*
	Pinkie's Balloon Fight
	Copyright (C) 2012  dancinninja (dancinninjac@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "LiveObject.h"
#include "Platform.h"

//----------------------------------------
// Default Constructor
//----------------------------------------

// Temporary variables!!
LiveObject::LiveObject(){
	x = 0;
	y = 0;
	xAccel = 0;
	yAccel = 0;
	width = 50;
	height = 50;
	lives = 1;
	horizontalDirection = NONE;
	alive = true;
	readyToJump = true;
}

LiveObject::~LiveObject(){
	// Nothing to clean up
}


// Display it on the screen
void LiveObject::Render(){

	// TODO: Make this Wii-specific
	glLoadIdentity();
	
	glTranslatef(x, y, -1);
	glScalef(width, height, 1);
	glColor4ub(255,255,255,255);

	//*
	// FOR TESTING
	glColor4ub(100,255,255,255);
	glDisable(GL_TEXTURE_2D);
	glBegin(GL_QUADS);
		glVertex3f(0.0f, 0.0f, 0.0f);
		glVertex3f(1.0f, 0.0f, 0.0f);
		glVertex3f(1.0f, 1.0f, 0.0f);
		glVertex3f(0.0f, 1.0f, 0.0f);
	glEnd();
	glEnable(GL_TEXTURE_2D);
	//*/
	/*
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 1.0f, 0.0f);
	glEnd();
	//*/
}

// Update the variables
void LiveObject::Update(){

	x += xAccel;
	y += yAccel;
	// Moved gravity into the Player class.
	// Each enemy and object may behave differently 
	// (Such as just moving in a straight horizontal line)

	//TODO: PUT INTO OWN CLASS AND MAKE DYNAMIC!
	// FOR TESTING PURPOSES ONLY!
	if(x < -50){
		//x = 740;
		SetPosition(740,y);
	}
	else if(x > 740){
		//x = -50;
		SetPosition(-50,y);
	}
	if(y < 0){
		//y = 0;
		SetPosition(x,0);
		// Have it bounce off the bottom
		yAccel /= -4;
		xAccel /= 4;
	}
	else if(y > 480){
		SetPosition(x,480);
		// Bump into the ceiling
		yAccel /=4;
	}
	// END TESTING

}

// Change the direction that the object is going to be moving 
//	dir: (-1: left | 0: still | 1: right)
void LiveObject::ChangeDirection(DIRECTION dir){
	horizontalDirection = dir;
}

// Have them "jump" or flap their wings
void LiveObject::Jump(){
		
	readyToJump = false;
	yAccel += VIRTICAL_JUMP_ACCEL;
	xAccel += HORIZONTAL_DIR_ACCEL * horizontalDirection;
}

bool LiveObject::IsReadyToJump() const{
	return readyToJump;
}

void LiveObject::SetReadyToJump(){
	readyToJump = true;
}

bool LiveObject::CollideWithPlatform(Platform& platform){

	// Check for the Vertical section (x-axis)
	if(x + width > platform.x){
		//  ooo   | 
		//  ooo   | 
		//   |    |
		//   |----|
		//   |    |
		if(x < platform.x + platform.width){
			//   |   ooo
			//   |   ooo
			//   |    |
			//   |----|
			//   |    |
			// Check for the Horizontal section (y-axis)
			if(y < platform.y + platform.height && y + height > platform.y){
				//   |    |
				//   |    |
				//   |   ooo
				//   |---ooo
				//   |    |

				// We know for certain that we've hit the target. The question is, where?
				// From the top, bottom, left or right sides?

				// Check if we are completely within the vertical lines of the platform
				if(x + width - HIT_TEST_THRESHOLD > platform.x){

					if(x + HIT_TEST_THRESHOLD  < platform.x + platform.width){
						// We are now certain that we're within the vertical AND horizonatal lines
						//   |    |
						//   |    |
						//   | ooo|
						//   |-ooo|
						//   |    |	
						// If we're falling, it hits the top from above
						if(yAccel < 0){
							y = platform.y + platform.height;
							// Have it bounce off
							yAccel /= -HIT_Y_DECEL;
							xAccel /= HIT_X_DECEL;
						}else{ // It's below going up
							//   |    |
							//   |    |
							//   |    |
							//   |-ooo|
							//   | ooo|
							y = platform.y - height;
							// Bump into the ceiling
							yAccel /= -HIT_Y_DECEL;	
						}
					}else{
						// We're hitting it on the right side of the platform
						//        |
						//        |
						//        |ooo
						//   |----|ooo
						//        |
						x = platform.x + platform.width;
						xAccel /= -HIT_X_DECEL;
					}
				}else{
					// We're hitting it on the left side of the platform
					//        |
					//        |
					//ooo     |
					//ooo|----|
					//        |
					x = platform.x - width;
					xAccel /= -HIT_X_DECEL;
					
				}

				// We have hit the platform
				return true;
			}
		}
	}

	// We checked everything, and we're not hitting any platforms
	return false;
}


// Ouch! It got hit!
void LiveObject::GetHit(){
	lives--;
	// Are they dead yet?
	if(lives <= 0){
		Die();
	}
}

bool LiveObject::IsAlive() const{
	return alive;
}

// Eliminate them, stop drawing them.
void LiveObject::Die(){
	// Stop drawing them
	alive = false;
}
